package org.sfx.diagnostics

import javafx.scene.Node
import javafx.beans.value.ObservableValue
import javafx.collections.ObservableList
import org.sfx.rich.Enrich._
import scala.collection.JavaConverters._
//import org.sfx.collections.CompositeObservableList
import javafx.collections.FXCollections
import javafx.scene.control.TextField
import javafx.event.EventHandler
import javafx.scene.input.KeyEvent
import javafx.scene.input.KeyCode
import javafx.scene.layout.HBox
import javafx.scene.control.Label
import javafx.scene.Scene
import org.sfx.util.Accessor
import org.sfx.util.ObjectGetter
import org.sfx.util.StringGetter
import org.sfx.util.StringSetter

case class SpyInfo(val name: String, val item: Object) {
  def value: Object = item match {
    case null => null
    case observableValue: ObservableValue[Nothing] => observableValue.getValue()
    case x => x
  }
  
  def stringValue: String = itemString
  
  def stringValue_=(value: String): Unit = item match {
    case null => null
    case accessor: StringSetter => {
      println("--> a string")
      accessor.stringValue = value
    }
    case a: Accessor => {
      println("--> something else: " + a.subject)
    }
    case x => {
      x
    }
  }
  
  def isLeaf: Boolean = item match {
    case null => true
    case observableValue: ObservableList[Nothing] => false
    case _ => true//children.size == 0
  }
  
  def itemString: String = value match {
    case null => "null"
    case accessor: StringGetter => accessor.stringValue
    case x => x.toString()
  }
  
  def kind: SpyKind = item match {
    case control: StringSetter => {
      SpyKind.WritableProperty
    }
    case control: StringGetter => {
      SpyKind.ReadableProperty
    }
    case control: ObservableList[_] => {
      SpyKind.ObservableList
    }
    case _ => SpyKind.ReadableValue
  }

//  lazy val children = {
//    //var composite: CompositeObservableList[SpyInfo] = new CompositeObservableList[SpyInfo]()
//    
//    if (this.value != null) {
//      val list: ObservableList[SpyInfo] = FXCollections.observableArrayList()
//      
//      this.value match {
//        case observableList: ObservableList[_] => {
//          observableList.asInstanceOf[ObservableList[Object]].translateInto(list) { thing =>
//            SpyInfo("[?]", thing)
//          }
//        }
//        case objectGetter: ObjectGetter => {
//          Option(objectGetter.objectValue).map { objectValue =>
//            /*val items1 = objectValue._observableLists.toList.sortBy(_._1).map { case (name, observableList) =>
//              SpyInfo(name, observableList)
//            }
//            list.addAll(items1.asJava)*/
//          }
//          
//          Option(objectGetter.objectValue).map { objectValue =>
//            /*val items2 = objectValue._properties.toList.sortBy(_.name).map { namedProperty =>
//              SpyInfo(namedProperty.name, namedProperty)
//            }
//            list.addAll(items2.asJava)*/
//          }
//        }
//        case _ => {
//          /*val items1 = this.value._observableLists.toList.sortBy(_._1).map { case (name, observableList) =>
//            SpyInfo(name, observableList)
//          }
//          list.addAll(items1.asJava)
//          
//          val items2 = this.value._properties.toList.sortBy(_.name).map { namedProperty =>
//            SpyInfo(namedProperty.name, namedProperty)
//          }
//          list.addAll(items2.asJava)*/
//        }
//      }
//      
//      //composite.lists.add(list)
//    }
//    
//    //composite
//  }
}
